package com.mingqijia.gassafety.job.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gap.basic.base.CommonResponse;
import com.gap.cache.redis.RedisCache;
import com.mingqijia.gassafety.db.entity.BaseEntity;
import com.mingqijia.gassafety.db.entity.Dictionary;
import com.mingqijia.gassafety.db.entity.FuncArea;
import com.mingqijia.gassafety.db.mapper.ConsumerLocationMapper;
import com.mingqijia.gassafety.db.mapper.DictionaryMapper;
import com.mingqijia.gassafety.db.mapper.DtuMapper;
import com.mingqijia.gassafety.db.mapper.FuncAreaMapper;
import com.mingqijia.gassafety.job.request.OrganizationalDepartmentListRequest;
import com.mingqijia.gassafety.job.response.OrganizationalDepartmentResp;
import com.mingqijia.gassafety.job.response.VccOrganizationDepartmentListResponse;
import com.mingqijia.gassafety.job.response.VccOrganizationDepartmentPermissionResponse;
import com.mingqijia.gassafety.job.service.OrganizationalDepartmentExportService;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.OrgDepartmentEnum;
import com.mingqijia.gassafety.shared.dto.UserFuncCodePermissionDTO;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.vcc.VccSystemProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.mingqijia.gassafety.shared.constant.Constants.IS_DELETED_FALSE;

/**
 * @program: gassafety
 * @description: 组织部门实现
 * @author: zm
 * @create: 2024-07-30 13:42
 **/
@Service
@Slf4j
public class OrganizationalDepartmentServiceImpl implements OrganizationalDepartmentExportService {

    @Value(value = "${gassafety.ewt.url}")
    public String targetUrl;

    @Autowired
    VccSystemProvider vccSystemProvider;

    @Autowired
    ConsumerLocationMapper consumerLocationMapper;

    @Autowired
    DtuMapper dtuMapper;

    @Autowired
    FuncAreaMapper funcAreaMapper;

    @Autowired
    RedisCache redisCache;

    @Autowired
    DictionaryMapper dictionaryMapper;

    private static final String ORG_DEPARTMENT_TYPE = "org_department_type"; //      org_department_type


    public Map<String,String> queryDictMapByCodeNoSpId(String dictCode, Map<String,String> defaultMap) {
        Map<String,String> map = new HashMap<>();
        QueryWrapper<Dictionary> dictionaryQueryWrapper = new QueryWrapper<>();
        dictionaryQueryWrapper.lambda()
                .eq(Dictionary::getIsDeleted, IS_DELETED_FALSE)
                .eq(Dictionary::getSpId, "0")
                .eq(Dictionary::getDictCode, dictCode);
        List<Dictionary> dictionaryList = dictionaryMapper.selectList(dictionaryQueryWrapper);
        if (CollectionUtil.isNotEmpty(dictionaryList)) {
            map = dictionaryList.stream().collect(Collectors.toMap(Dictionary::getValue, Dictionary::getAlias,(k1,k2)->k2));
        }
        else {
            map = defaultMap;
        }
        if (MapUtils.isEmpty(map)) map = defaultMap;
        return map;
    }


    @Override
    public List<OrganizationalDepartmentResp> export(OrganizationalDepartmentListRequest req) {
        String spId = ApplicationUtils.getWorkingSpId();
        String userId = ApplicationUtils.getUserId();
        //  查询权限
        UserFuncCodePermissionDTO permissionResponse = getArea(spId, userId);
        log.info("权限查询结果：{}", permissionResponse);
        List<String> reqIds = new ArrayList<>();

        LambdaQueryWrapper<FuncArea> permissionQuery = new LambdaQueryWrapper<>();
        permissionQuery.eq(FuncArea::getSpId, spId)
                .eq(BaseEntity::getIsDeleted, false)
                .isNotNull(FuncArea::getDeptId);

        if (StringUtils.isNotEmpty(req.getFuncName())) {
            permissionQuery.like(FuncArea::getFuncName, "%"+ req.getFuncName()+"%");
        }
        if (CollectionUtils.isNotEmpty(permissionResponse.getFuncCodes())) {
            permissionQuery.in(FuncArea::getFuncCode, permissionResponse.getFuncCodes());
        }
        List<FuncArea> permissionAreas = funcAreaMapper.selectList(permissionQuery);
        if ((permissionResponse.getAuthority() == 0)) {
            reqIds = new ArrayList<>();
        }
        if (CollectionUtils.isNotEmpty(permissionAreas)) {
            reqIds = permissionAreas.stream().map(FuncArea::getDeptId).distinct().collect(Collectors.toList());
        }

        if (permissionResponse.getAuthority() == 1 && (CollectionUtils.isEmpty(permissionResponse.getFuncCodes()) || CollectionUtils.isEmpty(permissionAreas))) return new ArrayList<>();
        if (StringUtils.isNotEmpty(req.getFuncName()) && CollectionUtils.isEmpty(reqIds)) return  new ArrayList<>();

        String body = vccSystemProvider.org_depart_list(spId, req.getOrgName(), reqIds, targetUrl);
        log.info("组织部门列表返回结果：{}", body);
        if (StringUtils.isEmpty(body)) return new ArrayList<>();
        List<VccOrganizationDepartmentListResponse> allOrgDepts = JSONArray.parseArray(body, VccOrganizationDepartmentListResponse.class);
        if (CollectionUtils.isNotEmpty(allOrgDepts)) {
            List<String> deptIds = allOrgDepts.stream().map(VccOrganizationDepartmentListResponse::getId).collect(Collectors.toList());
            Map<String, List<FuncArea>> funcAreaMap = new HashMap<>();
            Map<String, Integer> countMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(deptIds)) {
                LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(FuncArea::getSpId, spId)
                        .eq(BaseEntity::getIsDeleted, false)
                        .isNotNull(FuncArea::getDeptId)
                        .in(FuncArea::getDeptId, deptIds);
                List<FuncArea> funcAreas = funcAreaMapper.selectList(queryWrapper);
                if (CollectionUtils.isNotEmpty(funcAreas)) {
                    funcAreaMap = funcAreas.stream().collect(Collectors.groupingBy(FuncArea::getDeptId));
                }
                List<FuncArea> countList = funcAreaMapper.queryCountByDeptIds(deptIds);
                if (CollectionUtils.isNotEmpty(countList)) {
                    countMap = countList.stream().collect(Collectors.toMap(FuncArea::getDeptId, FuncArea::getPid));
                }
            }
            List<OrganizationalDepartmentResp> tempDepts = new ArrayList<>();
            Map<String,String> orgTypeMap = queryDictMapByCodeNoSpId(ORG_DEPARTMENT_TYPE, OrgDepartmentEnum.toMap());


            for (VccOrganizationDepartmentListResponse item : allOrgDepts) {
                OrganizationalDepartmentResp response = new OrganizationalDepartmentResp();
                BeanUtils.copyProperties(item, response);
                if (MapUtils.isNotEmpty(funcAreaMap) && funcAreaMap.containsKey(item.getId()) && CollectionUtils.isNotEmpty(funcAreaMap.get(item.getId()))) {
                    response.setFuncName(funcAreaMap.get(item.getId()).stream().map(FuncArea::getFuncName).collect(Collectors.joining("、")));
                }
                if (MapUtils.isNotEmpty(countMap) && countMap.containsKey(item.getId())) {
                    response.setInstallSum(countMap.get(item.getId()));
                }
                if (MapUtils.isNotEmpty(orgTypeMap) && orgTypeMap.containsKey(item.getOrgType())) {
                    response.setOrgTypeName(orgTypeMap.get(item.getOrgType()));
                }

                tempDepts.add(response);
            }
            return tempDepts;
        }
        return new ArrayList<>();
    }

    public VccOrganizationDepartmentPermissionResponse getPermissionIds(String spId , String userId) {
        String body = vccSystemProvider.org_depart_ids(userId,spId, targetUrl);
        log.info("组织部门ids返回结果：{}", body);
        if (StringUtils.isEmpty(body)) {
            log.info("获取组织部门ids失败！");
        }
        return JSONObject.parseObject(body, VccOrganizationDepartmentPermissionResponse.class);
    }

    /**
     * 查询区域
     * @param spId
     * @param userId
     */
    @Override
    public UserFuncCodePermissionDTO getArea(String spId , String userId) {
        String key = Constants.LOGIN_USER_PERMISSION_REDIS_KEY+":"+userId;
        String retStr = redisCache.getCacheObject(key);
        UserFuncCodePermissionDTO result = new UserFuncCodePermissionDTO();
        if( StringUtils.isNotEmpty(retStr) ){
            try{
                result = JSONObject.parseObject(retStr, UserFuncCodePermissionDTO.class);
            }catch (Exception e){
                result = null;
                log.error("解析用户数据权限报错",e);
            }
        }
        int authority = -1;
        List<String> funcCodes = new ArrayList<>();
        List<Integer> funcIds = new ArrayList<>();
        if( null == result || null == result.getAuthority() ){
            VccOrganizationDepartmentPermissionResponse permissionResponse = getPermissionIds(spId, userId);
            result = new UserFuncCodePermissionDTO();
            if (null == permissionResponse || null == permissionResponse.getAuthority()) {
                log.info("未配置该账号{}:{}的数据权限！",spId,userId);
                result.setAuthority(authority);
                result.setFuncCodes(funcCodes);
                result.setFuncIds(funcIds);
                //throw new RuntimeException("未配置该账号的数据权限,请先配置");
            }else{
                authority = permissionResponse.getAuthority();
                funcCodes = new ArrayList<>();
                if ( 1 == authority ) {
                    List<String> reqIds = permissionResponse.getOrgIdList();
                    LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(FuncArea::getSpId, spId)
                            .eq(BaseEntity::getIsDeleted, false);
                    if (CollectionUtils.isNotEmpty(reqIds)) {
                        queryWrapper.in(FuncArea::getDeptId, reqIds);
                    }
                    List<FuncArea> funcAreas = funcAreaMapper.selectList(queryWrapper);
                    funcCodes = funcAreas.stream().map(FuncArea::getFuncCode).collect(Collectors.toList());
                    funcIds = funcAreas.stream().map(FuncArea::getId).collect(Collectors.toList());
                }
                result.setAuthority(authority);
                result.setFuncCodes(funcCodes);
                result.setFuncIds(funcIds);
                redisCache.setCacheObject(key,JSONObject.toJSONString(result), 24*60*60, TimeUnit.SECONDS);
            }
        }
        return result;
    }
}
